package edu.pw.treegrid.server.web;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;

import edu.pw.treegrid.server.message.Hierarchy;
import edu.pw.treegrid.server.message.Path;
import edu.pw.treegrid.server.message.Request;
import edu.pw.treegrid.server.message.ResponseFetchChilds;
import edu.pw.treegrid.server.model.DomainField;
import edu.pw.treegrid.server.model.DomainObject;
import edu.pw.treegrid.server.query.QueryGenerator;
import edu.pw.treegrid.server.reportmodel.Report;
import edu.pw.treegrid.server.reportmodel.ReportColumn;
import edu.pw.treegrid.server.reportmodel.ReportSimpleColumn;
import edu.pw.treegrid.server.service.DatabaseConnector;
import edu.pw.treegrid.server.service.TableRow2DomainObjectConverter;
import edu.pw.treegrid.server.service.TreeGridService;
import edu.pw.treegrid.server.service.TreeGridServiceImpl;
import edu.pw.treegrid.server.service.XMLMarshaller;
import edu.pw.treegrid.shared.ReportColumnCategory;
import edu.pw.treegrid.shared.ReportColumnDescription;
import edu.pw.treegrid.shared.ReportColumnType;

@Deprecated
public class ReportController {
	protected static final String PATH_SEPARATOR = ";";
	

	
	public ReportController(DataSource dataSource) {
		//TODO
		//to powinno byc ustawione poprzez XML
		this.setMarshaller(new XMLMarshaller());
		TreeGridServiceImpl service = new TreeGridServiceImpl();
		service.setConverter(new TableRow2DomainObjectConverter());
		service.setDataSource(dataSource);
		service.setQueryGenerator(new QueryGenerator());
		this.setService(service);
	}
	
	private XMLMarshaller marshaller;
	
	private TreeGridService service;
	
	public void setMarshaller(XMLMarshaller marshaller) {
		this.marshaller = marshaller;
	}
	
	public XMLMarshaller getMarshaller() {
		return marshaller;
	}



	public void setService(TreeGridService service) {
		this.service = service;
	}

	public TreeGridService getService() {
		return service;
	}

	public List<Record> fetchMetaModel(String reportId) {
		Report report = getReportById(reportId);
		List<Record> records = new LinkedList<Record>();
		for(ReportColumnDescription rcd : getReportColumnDescriptions(report)) {
			records.add(convertReportColumnDesc(rcd));
		}
		
		return records;
	}
	
	public List<Record> fetchData(
			String reportId
			, String parentPath
			, String hierarchy
		)
	{
		Request requestFetchChilds = new Request();
		//TODO filter:
		//requestFetchChilds.setFilter(filter);
		Report report = getReportById(reportId);
		requestFetchChilds.setPath(buildPathFromString(parentPath));
		requestFetchChilds.setReport(report);
		requestFetchChilds.setHierarchy(buildHierarchyFromString(report, hierarchy));
		ResponseFetchChilds responseFetchChilds = new ResponseFetchChilds();
		
		service.fetchChilds(requestFetchChilds, responseFetchChilds);
		
		return convert(responseFetchChilds.getDomainObjects());
	}
	
	private Report getReportById(String reportId) {
		return marshaller.deserializeReport(reportId);
	}

	public Path buildPathFromString(String parentPath) {
		Path result = new Path();

		for(String s: parentPath.split(PATH_SEPARATOR)) {
			result.addNode(s);
		}
		return result;
	}

	public Hierarchy buildHierarchyFromString(Report report, String hierarchy) {
		Hierarchy h = new Hierarchy();
		
		if(hierarchy != null) {
			String trimHierarchy = hierarchy.trim();
			if(!trimHierarchy.equals("")) {
				for(String s: hierarchy.split(PATH_SEPARATOR)) {
					h.addGroupColumn(report.getColumnByName(s));
				}
			}
		}
		
		return h;
	}

	public String exportExcel(String reportId) {
		return "excelView";
	}
	
	private Record convertReportColumnDesc(ReportColumnDescription rcd) {
		Record result = new Record();
		
		result.addParam(ReportColumnDescription.NAME, rcd.getName());
		result.addParam(ReportColumnDescription.TITLE, rcd.getTitle());
		result.addParam(ReportColumnDescription.TYPE, rcd.getType());
		result.addParam(ReportColumnDescription.IMAGE_SRC, rcd.getImageSrc());
		result.addParam(ReportColumnDescription.CATEGORY, rcd.getCategory());
		result.addParam(ReportColumnDescription.FORMAT, rcd.getFormat());
		
		return result;
	}
	
	public ReportColumnDescription convert(ReportColumn column) {
		ReportColumnDescription description = new ReportColumnDescriptionServer();
		
		ReportSimpleColumn rsc = column.getReportSimpleColumn();
		description.setCategory(rsc.getCategory());
		description.setImageSrc(rsc.getImageSrc());
		description.setName(rsc.getName());
		description.setTitle(rsc.getTitle());
		description.setType(rsc.getType());
		description.setFormat(rsc.getFormat());
		
		return description;
	}
	
	public List<ReportColumnDescription> getReportColumnDescriptions(Report report) {
		List<ReportColumnDescription> result = new LinkedList<ReportColumnDescription>();
		
		result.add(new ReportColumnDescriptionServer(ReportColumnDescriptionServer.PATH_COLUMN, "path", ReportColumnType.TEXT, "", ReportColumnCategory.SPECIAL, ""));
		result.add(new ReportColumnDescriptionServer(ReportColumnDescriptionServer.PARENT_PATH_COLUMN, "parentPath", ReportColumnType.TEXT, "", ReportColumnCategory.SPECIAL, ""));
		result.add(new ReportColumnDescriptionServer(ReportColumnDescriptionServer.NAME_COLUMN, "Name", ReportColumnType.TEXT, "", ReportColumnCategory.SPECIAL, ""));
		
		for(ReportColumn c: report.getColumns()) {
			result.add(convert(c));
		}
		
		return result;
	}
	
	public List<Record> convert(Collection<DomainObject> objects) {
		List<Record> records = new LinkedList<Record>();
		for(DomainObject object : objects) {
			records.add(convert(object));
		}
		return records;
	}
	
	public Record convert(DomainObject object) {
		Record r = new Record();
		Path path = object.getPath();
		Path parentPath = object.getParentPath();
		
		r.addParam(ReportColumnDescriptionServer.PATH_COLUMN, buildPathString(path));
		r.addParam(ReportColumnDescriptionServer.PARENT_PATH_COLUMN, buildPathString(parentPath));
		r.addParam(ReportColumnDescriptionServer.NAME_COLUMN, object.getName());
		r.addParam(ReportColumnDescriptionServer.IMAGE_SRC, object.getImageSrc());
		r.addParam(ReportColumnDescriptionServer.FOLDER_COLUMN, object.isFolder());
		
		for(DomainField df : object.getDomainField()) {
			r.addParam(df.getReportColumn().getName(), df.getValue());
		}
		
		return r;
	}
	
	public String buildPathString(Path path) {
		StringBuilder sb = new StringBuilder();
		
		boolean first = true;
		for(Object s : path.getPath()) {
			if(!first) {
				sb.append(PATH_SEPARATOR);
			}
			else {
				first = false;
			}
			sb.append(s != null ? s.toString() : "null");
		}
		
		return sb.toString();
	}
}
